import 'dart:async';

import 'package:flutter/material.dart';
import 'package:qgchat/bloc/blocProvider.dart';
import 'package:qgchat/common/action/filter/index.dart';
import 'package:qgchat/common/action/index.dart';
import 'package:qgchat/common/class/eventBus/index.dart';
import 'package:qgchat/common/class/websocket/index.dart';
import 'package:qgchat/common/global/global.dart';
import 'package:qgchat/http/apis/common.dart';
import 'package:qgchat/http/models/chatModel.dart';
import 'package:qgchat/http/models/textModel.dart';
import 'package:qgchat/states/states_model/index.dart';

class ChatInfoBloc implements BlocBase {
  // ##########  STREAMS  ##############

  /// 私聊列表 stream
  StreamController _chat = StreamController.broadcast();
  Sink get _chatSink => _chat.sink;
  Stream get chatStream => _chat.stream;

  /// 显隐emoji stream
  StreamController _showEmoji = StreamController<bool>.broadcast();
  Sink get _emojiSink => _showEmoji.sink;
  Stream get emojiStream => _showEmoji.stream;

  // ##########  VARIABLE  ##############

  // 对方token
  String targetToken;

  // emoji显示状态
  bool showEmoji = false;

  // 全部键盘关闭
  bool allKeyboardHide = false;

  // ##########  DEFAULT  ##############

  /// 默认是否显示emoji
  final bool showEmojiDefault = false;

  /// 私信列表控制器
  ScrollController listviewC = ScrollController();

  /// 私信输入框控制器
  TextEditingController textFieldC = TextEditingController();

  // 输入框焦点
  FocusNode focus = FocusNode();

  /// socket
  WebSocket ws = Global.ws;

  /// 私聊对话
  List<Msglist> dialogue = [];

  ChatInfoBloc(targetToken) {
    // 监听键盘焦点事件
    listenKeyboard();

    // 查询本地数据库
    queryDbHistory(targetToken);

    bus.on("listenMessage", _listenMessage);
  }

  void dispose() {
    _chat.close();
    _showEmoji.close();
  }

  // ##########  HANDLING  ##############

  /// 整理私聊对话(对话间隔超过5分钟出现时间提示)
  List<Msglist> sortOut(List<Msglist> dialogueList) {
    int interval = 300; // 两条数据之间时间相差多少出现时间

    List<Msglist> list = [];

    if (dialogueList.length > 0) {
      list.add(createDate(dialogueList[0])); // 先插入第一条数据的时间
    }

    for (var i = 0; i < dialogueList.length; i++) {
      if (i > 0 &&
          i + 1 < dialogueList.length &&
          dialogueList[i].createtime <
              dialogueList[i + 1].createtime - interval) {
        list.add(createDate(dialogueList[i + 1]));
      }
      list.add(dialogueList[i]);
    }
    return list;
  }

  /// 生成时间数据
  Msglist createDate(Msglist item) {
    return Msglist(
      token: item.token,
      userToken: item.userToken,
      message: item.message,
      type: 2,
      userName: item.userName,
      userHead: item.userHead,
      isread: 0,
      createtime: item.createtime,
    );
  }

  /// 查询本地数据库
  void queryDbHistory(targetToken) async {
    ChatModel chatInfo = await Global.db.queryDialogue(targetToken);
    dialogue = sortOut(chatInfo?.msglist ?? []);
    _chatSink.add(true);
  }

  /// 选择emoji
  void sendEmoji(String emoji) {
    textFieldC.text = textFieldC.text + emoji;
    textFieldC.selection = TextSelection.collapsed(
      offset: textFieldC.text.length,
      affinity: TextAffinity.downstream,
    );
  }

  /// 显隐emoji
  void toggle(context) {
    if (showEmoji) {
      if (!focus.hasFocus) {
        FocusScope.of(context).requestFocus(focus);
      }
      _emojiSink.add(false);
      showEmoji = false;
    } else {
      if (focus.hasFocus) {
        focus.unfocus();
      }
      _emojiSink.add(true);
      showEmoji = true;
    }
  }

  /// 隐藏emoji以及键盘
  void hideKeyboard() {
    _emojiSink.add(false);
    showEmoji = false;
    allKeyboardHide = true;
    focus.unfocus();
  }

  /// 监听键盘焦点事件
  void listenKeyboard() {
    focus.addListener(() {
      if (focus.hasFocus) {
        _emojiSink.add(false);
        showEmoji = false;
      } else {
        if (allKeyboardHide) {
          allKeyboardHide = false;
        } else {
          showEmoji = true;
          _emojiSink.add(true);
        }
      }
    });
  }

  /// 添加消息
  void _addMsg(int type, Map data) {
    UserState userState = state(Global.context, 'user');

    int time = (DateTime.now().millisecondsSinceEpoch / 1000).floor();
    Msglist insert = Msglist(
      token: data['token'],
      userToken: userState.info.memberToken,
      message: data['msg'],
      type: type,
      userName: data['name'],
      userHead: data['head'],
      isread: 0,
      createtime: time,
      label: data['label'],
    );

    if (dialogue.length == 0 || dialogue.last.createtime < time - 300) {
      dialogue.add(createDate(insert));
    }
    dialogue.add(insert);

    if (!_chat.isClosed) {
      _chatSink.add(true);
    }
  }

  /// 监听消息
  void _listenMessage(data) {
    _addMsg(1, data);
  }

  /// 发送私信
  void sendMessage(String targetToken, String userName, String userHead) async {
    if (textFieldC.text.isEmpty) {
      showToast('你还没说话呢');
      return;
    }

    Map data = {
      "token": targetToken,
      "msg": Filter.txt(textFieldC.text),
      "name": userName,
      "head": userHead,
    };

    // 清空输入框
    textFieldC.clear();

    // 阿里文本检测
    List<TextModel> textModel = await CommonApis.text(data['msg']);
    if (textModel.length > 0) {
      String status = textModel[0]?.results[0]?.label;
      Map textLabel = {
        // "normal": "",
        "spam": "含垃圾信息",
        "ad": "广告",
        "politics": "涉政",
        "terrorism": "暴恐",
        "abuse": "辱骂",
        "porn": "色情",
        "flood": "灌水",
        "contraband": "违禁",
        "meaningless": "无意义",
        "customized": "未知",
      };
      if (textLabel.containsKey(status)) {
        data['label'] = textLabel[status];
        _addMsg(3, data);
        return;
      }
    }

    // 发送私信
    SocketState socketState = (state(Global.context, 'socket') as SocketState);
    socketState.sendMessage(targetToken, data['msg'], userName, userHead);

    _addMsg(0, data);
  }
}
